#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>

int main(int argc, char *argv[]) {
    int ret;
    struct sockaddr_nl *nl;  // 瀹氫箟涓€涓寚鍚?struct sockaddr_nl 缁撴瀯浣撶殑鎸囬拡 nl
    int len = 0;
    char buf[4096] = {0};  // 鏁版嵁鎺ユ敹缂撳啿鍖?
    int i = 0;

    bzero(nl, sizeof(struct sockaddr_nl));  // 灏?nl 鎸囧悜鐨勫唴瀛樺尯鍩熸竻闆讹紝纭繚缁撴瀯浣撶殑瀛楁鍒濆鍖栦负0
    nl->nl_family = AF_NETLINK;  // 璁剧疆 nl 缁撴瀯浣撶殑 nl_family 瀛楁涓?AF_NETLINK锛屾寚瀹氬湴鍧€鏃忎负 Netlink
    nl->nl_pid = 0;  // 璁剧疆 nl 缁撴瀯浣撶殑 nl_pid 瀛楁涓?0锛岃〃绀虹洰鏍囪繘绋?ID 涓?0锛屽嵆骞挎挱缁欐墍鏈夎繘绋?
    nl->nl_groups = 1;  // 璁剧疆 nl 缁撴瀯浣撶殑 nl_groups 瀛楁涓?1锛岃〃绀哄彧鎺ユ敹鍩烘湰缁勭殑鍐呮牳浜嬩欢

    int socket_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);  // 鍒涘缓涓€涓?Netlink 濂楁帴瀛?
    if (socket_fd < 0) {
        printf("socket error\n");
        return -1;
    }

    ret = bind(socket_fd, (struct sockaddr *)nl, sizeof(struct sockaddr_nl));  // 浣跨敤 bind 鍑芥暟灏?socket_fd 濂楁帴瀛椾笌 nl 鍦板潃缁撴瀯浣撶粦瀹氬湪涓€璧?
    if (ret < 0) {
        printf("bind error\n");
        return -1;
    }

    while (1) {
        bzero(buf, 4096);  // 灏嗙紦鍐插尯 buf 娓呴浂锛岀‘淇濇暟鎹帴鏀跺墠鐨勫垵濮嬪寲
        len = recv(socket_fd, &buf, 4096, 0);  // 浠?socket_fd 濂楁帴瀛楁帴鏀舵暟鎹紝瀛樺偍鍒扮紦鍐插尯 buf 涓紝鏈€澶ф帴鏀跺瓧鑺傛暟涓?4096

        for (i = 0; i < len; i++) {
            if (*(buf + i) == '\0') {  // 濡傛灉鎺ユ敹鍒扮殑鏁版嵁涓湁 '\0' 瀛楃锛屽皢鍏舵浛鎹负 '\n'锛屼互渚垮湪鎵撳嵃鏃舵崲琛屾樉绀?
                buf[i] = '\n';
            }
        }

        printf("%s\n", buf);  // 鎵撳嵃鎺ユ敹鍒扮殑鏁版嵁
    }

    return 0;
}
